package com.xuecheng.media.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.xuecheng.media.model.po.MediaProcess;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;

import java.util.List;

/**
 * <p>
 *  Mapper 接口
 * </p>
 *
 * @author itcast
 */
public interface MediaProcessMapper extends BaseMapper<MediaProcess> {
    //例如现在是2台处理器 则编号为0 和 1
    //例如现在的待处理任务的id为1 然后shardTotal处理机有2台 则1%2（取余）= 1 则表示分片为1的处理机领取到任务
    //status=1表示未处理 2表示处理成功 3表示处理失败  fail_count表示处理失败的次数 如果3次都处理失败就不要这个任务了
    //相当于领取任务和分配任务 根据shardIndex进行任务的分配
    //LIMIT #{count}表示每次只查固定数量的任务 因为任务可能有很多
    @Select("select * from media_process mp where mp.id % #{shardTotal} =  #{shardIndex} and (mp.status=1 or mp.status=3) and mp.fail_count<3 LIMIT #{count}")
    List<MediaProcess> selectListByShardIndex(@Param("shardTotal") int shardTotal, @Param("shardIndex") int shardIndex, @Param("count") int count);

    /**
     * 开启一个任务   乐观锁保证幂等性
     * @param id 任务id
     * @return 更新记录数
     */
    //status=4标表示任务处理中 这个是进行枪锁开启一个任务并没有执行任务 哪个线程抢到锁哪个线程就去执行任务 抢到锁以后就进行上锁后续再执行任务则这个任务上锁了其他线程就不能执行了
    // 乐观锁就是多个线程同时执行下面的sql语句 谁把这个sql语句执行成功了就获得了这个任务的执行权也就是上了锁
    // 哪个线程抢到这个锁就把这个任务进行上锁 然后再交给这个线程进行后续的视频转码
    // m.id=#{id}表示 开启任务需要一个任务的id 语法里面就有的啊 没有where就把全部任务都执行更新了 加上where的m.id=#{id}才确保是一个线程执行对应的一条记录进行修改
    //(m.status='1' or m.status='3')表示的就是版本号的意思
    //只有1或3也就是未处理或则处理失败的版本才可以进行sql语句的执行 当执行成功后把版本号修改成了4 则下一个线程再过来就不会执行成功因为执行的条件是版本为1或则3
    @Update("update media_process m set m.status='4' where (m.status='1' or m.status='3') and m.fail_count<3 and m.id=#{id}")
    int startTask(@Param("id") long id);
}
